home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / FE1.ARJ / BMP.CPP next >
C/C++ Source or Header  |  1992-02-07  |  18KB  |  700 lines

  1. #include <math.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4.  
  5. #include "bmp.h"
  6.  
  7. const char editmap :: mode_s = 'S' ;
  8. const char editmap :: mode_x = 'X' ;
  9. const char *editmap :: mode_str = "MODE:%c" ;
  10.  
  11. editmap :: editmap ( int wd, int hg, char *fn ) :
  12. win( 0, 0, fg.displaybox[FG_X2], fg.displaybox[FG_Y2], FG_WHITE,
  13.     FG_BLACK, NULL, 19, 2 ), w( wd ), h( hg ), draw_func( draw_pixel ),
  14.     filename( fn ), clipb( NULL )
  15. {
  16. #define MOSTLENGTH    13
  17. #define MOSTLENGTHP1    14
  18. #define MOSTLENGTHP2    15
  19.  
  20.     int i ;
  21.     fg_coord_t k ;
  22.  
  23.     bits = alloc_array( w, h ) ;
  24.     mode = new char [MOSTLENGTH] ;
  25.     func = new char [MOSTLENGTH] ;
  26.  
  27.     sprintf( mode, mode_str, mode_s ) ;
  28.  
  29.     for ( i = 0 ; i < w ; i++ )
  30.         memset( bits[i], 0, h ) ;
  31.  
  32.     cellbox[FG_X1] = cellbox[FG_Y1] = 0 ;
  33.     cellbox[FG_X2] =
  34.         ( fg.displaybox[FG_X2] -
  35.             fg.charbox[FG_X2] * MOSTLENGTHP2 ) / w ;
  36.     cellbox[FG_Y2] = ( fg.displaybox[FG_Y2] - fg.charbox[FG_Y2] * 2 ) / h ;
  37.  
  38.     fg_make_box( pix, -1, -1, -1, -1 ) ;
  39.     fg_make_box( editbox, 0, 0, cellbox[FG_X2] * w, cellbox[FG_Y2] * h );
  40.     editbox[FG_X1] += fg.charbox[FG_X2] ;
  41.     editbox[FG_X2] += fg.charbox[FG_X2] ;
  42.     editbox[FG_Y1] += fg.charbox[FG_Y2] ;
  43.     editbox[FG_Y2] += fg.charbox[FG_Y2] ;
  44.  
  45.     kbd->add_script( 'q', destroy ) ;
  46.     kbd->add_script( 'l', _set_draw_line ) ;
  47.     kbd->add_script( 'p', _set_draw_pixel ) ;
  48.     kbd->add_script( 'r', _redraw ) ;
  49.     kbd->add_script( 'f', _set_floodfill ) ;
  50.     kbd->add_script( 'c', _set_draw_circle ) ;
  51.     kbd->add_script( 'e', _set_draw_ellipse ) ;
  52.     kbd->add_script( 'b', _set_draw_box ) ;
  53.     kbd->add_script( 'm', set_mode ) ;
  54.     kbd->add_script( 'i', _set_invert_box ) ;
  55.     kbd->add_script( 'a', _set_clear ) ;
  56.     kbd->add_script( 'y', _set_copy ) ;
  57.     kbd->add_script( 'u', _set_cut ) ;
  58.     kbd->add_script( 'z', _set_paste ) ;
  59.     kbd->add_script( 'x', byebye ) ;
  60.     kbd->add_script( 's', save ) ;
  61.     kbd->add_script( ',', _set_flip_x ) ;
  62.     kbd->add_script( '.', _set_flip_y ) ;
  63.     kbd->add_script( '\x1b', finish_func ) ;
  64.     box->add_script( editbox, edit_map ) ;
  65.     box->add_script( winbox, total_map ) ;
  66.     k = fg.displaybox[FG_X2] - fg.charbox[FG_X2] * MOSTLENGTH ;
  67.     fg_make_box( dispbox, k, fg.charbox[FG_Y2], k + w - 1,
  68.         fg.charbox[FG_Y2] + h - 1 ) ;
  69. #define ITEMS    24
  70.     mu = new menu ( k, fg.displaybox[FG_Y2] - fg.charbox[FG_Y2] * ITEMS,
  71.         MOSTLENGTH -  2, ITEMS, this ) ;
  72.  
  73.     strcpy( func, "PIXEL" ) ;
  74.     mu->add_item( '\x0', "[P]ixel", _set_draw_pixel ) ;
  75.     mu->add_item( '\x0', "[L]ine", _set_draw_line ) ;
  76.     mu->add_item( '\x0', "[B]ox", _set_draw_box ) ;
  77.     mu->add_item( '\x0', "[C]ircle", _set_draw_circle ) ;
  78.     mu->add_item( '\x0', "[E]llipse", _set_draw_ellipse ) ;
  79.     mu->add_item( '\x0', "[F]ill", _set_floodfill ) ;
  80.     mu->add_item( '\x0', "[I]nvert", _set_invert_box ) ;
  81.     mu->add_item( '\x0', "--------", NULL ) ;
  82.     mu->add_item( '\x0', "Cop[Y]", _set_copy ) ;
  83.     mu->add_item( '\x0', "C[U]t", _set_cut ) ;
  84.     mu->add_item( '\x0', "Paste[Z]", _set_paste ) ;
  85.     mu->add_item( '\x0', "Cle[A]r", _set_clear ) ;
  86.     mu->add_item( '\x0', "--------", NULL ) ;
  87.     mu->add_item( '\x0', "[M]ode", set_mode ) ;
  88.     mu->add_item( '\x0', "[R]edraw", _redraw ) ;
  89.     mu->add_item( '\x0', "FlipX[,]", _set_flip_x ) ;
  90.     mu->add_item( '\x0', "FlipY[.]", _set_flip_y ) ;
  91.     mu->add_item( '\x0', "--------", NULL ) ;
  92.     mu->add_item( '\x0', "[S]ave", save ) ;
  93.     mu->add_item( '\x0', "[Q]uit", destroy ) ;
  94.     mu->add_item( '\x0', "e[X]it", byebye ) ;
  95.     mu->add_item( '\x0', "--------", NULL ) ;    
  96.     mu->add_item( '\x0', func, NULL ) ;
  97.     mu->add_item( '\x0', mode, NULL ) ;
  98. }
  99.  
  100. void editmap :: delete_array ( char **a, int w ) {
  101.  
  102.     if ( a ) {
  103.         for ( int i = 0 ; i < w ; i++ )
  104.             delete a[i] ;
  105.         delete a ;
  106.     }
  107. }
  108.  
  109. char **editmap :: alloc_array ( int w, int h ) {
  110.  
  111.     char **x ;
  112.  
  113.     x = new char * [w] ;
  114.     for ( int i = 0 ; i < w ; i++ )
  115.         x[i] = new char [h] ;
  116.     return x ;
  117. }
  118.  
  119. void editmap :: realloc_array ( char ***x, int w, int h ) {
  120.  
  121.     if ( x )
  122.         delete_array( *x, w ) ;
  123.     *x = alloc_array( w, h ) ;
  124. }
  125.  
  126. editmap :: ~editmap () {
  127.  
  128.     int i ;
  129.  
  130.     delete_array( bits, w ) ;
  131.     delete_array( clipb, clip_w ) ;
  132.     delete mode ;
  133. }
  134.  
  135. void editmap :: byebye () { save() ; destroy() ; }
  136.  
  137. void editmap :: copymap ( char **b ) {
  138.  
  139.     int i, j ;
  140.  
  141.     for ( i = 0 ; i < w ; i++ )
  142.         for ( j = 0 ; j < h ; j++ )
  143.             bits[i][j] = b[i][j] ;
  144. }
  145.  
  146. void editmap :: save () {
  147.  
  148.     FILE *f ;
  149.     char *xn, *da ;
  150.     char *defna = "Untitled" ;
  151.     fg_box_t t ;
  152.     int i, j, k, m, kda, msk ;
  153.  
  154.     if ( ( f = fopen( xn = filename, "wt" ) ) == NULL )
  155.         if ( ( f = fopen( xn = defna, "wt" ) ) == NULL )
  156.             return ;
  157.     da = new char [w + 1] ;
  158.     fg_make_box( t, 0, 0, w - 1, h - 1 ) ;
  159.     fprintf( f, "fg_box_t %s_box = { 0, 0, %d, %d } ;\n", xn, w-1, h-1 ) ;
  160.     fprintf( f, "char %s_matrix[%u] = {\n", xn, fg_matrix_size( t ) ) ;
  161.  
  162.     for ( i = 0 ; i < h ; i++ ) {
  163.         fprintf( f, "\t" ) ;
  164.         for ( j = 0 ; j < w ; j++ )
  165.             da[j] = bits[j][h - i - 1] ? '#' : ' ' ;
  166.         da[j] = 0 ;
  167.         for ( k = 0 ; k < w ; k += 8 ) {
  168.             msk = 0x80 ;
  169.             for ( kda = 0, m = k ; m < k + 8 && m < w ; m++ ) {
  170.                 if ( bits[m][h - i - 1] )
  171.                     kda |= msk ;
  172.                 msk >>= 1 ;
  173.             }
  174.             fprintf(
  175.                 f, "0x%02x%c ",
  176.                 kda, k + 8 < w || i + 1 < h ? ',' : ' ' ) ;
  177.         }
  178.         fprintf( f,"\t/* %s */\n", da ) ;
  179.     }
  180.     fprintf( f, "} ;\n" ) ;
  181.     fclose( f ) ;
  182.     delete da ;
  183. }        
  184.  
  185. fg_color_t editmap :: get_color () {
  186.     return p_status == MSM_BUTTONL ? fgc : bgc ;
  187. }
  188.  
  189. int editmap :: get_mode () {
  190.     return mode[strlen(mode)-1] == mode_s ? FG_MODE_SET : FG_MODE_XOR ;
  191. }
  192.  
  193. void editmap :: set_mode () {
  194.  
  195.     if ( get_mode() == FG_MODE_SET )
  196.         sprintf( mode, mode_str, mode_x ) ;
  197.     else
  198.         sprintf( mode, mode_str, mode_s ) ;
  199.     mu->expose() ;
  200. }
  201.  
  202. void editmap :: getmspos () {
  203.  
  204.     p_status = msm_getstatus( &p_x, &p_y ) ;
  205.     p_y = fg.displaybox[FG_Y2] + 1 - p_y ;    
  206. }
  207.  
  208. void editmap :: translate () {
  209.  
  210.     p_x = ( p_x - editbox[FG_X1] ) / cellbox[FG_X2] ;
  211.     p_y = ( p_y - editbox[FG_Y1] ) / cellbox[FG_Y2] ;
  212. }
  213.  
  214. void editmap :: set_funcname ( eventscript_t e, char *n ) {
  215.  
  216.     draw_func = e ;
  217.     finish_func() ;
  218.     strcpy( func, n ) ;
  219.     mu->expose() ;
  220. }
  221.  
  222. void editmap :: _set_floodfill () { set_funcname( floodfill, "FILL" ) ; }
  223.  
  224. void editmap :: floodfill () {
  225.  
  226.     if ( pix[FG_X1] == -1 ) {
  227.         msm_hidecursor() ;
  228.         fg_fill( dispbox[FG_X1] + p_x, dispbox[FG_Y1] + p_y,
  229.             get_color(), get_color() ) ;
  230.         msm_showcursor() ;
  231.         redraw( 0, 0, w - 1, h - 1 ) ;
  232.         finish_func() ;
  233.     }
  234. }
  235.  
  236. void editmap :: _set_draw_line () { set_funcname( draw_line, "LINE" ) ; }
  237.  
  238. void editmap :: draw_line () {
  239.  
  240.     fg_coord_t x1, y1, x2, y2 ;
  241.  
  242.     if ( pix[FG_X1] == -1 ) {
  243.         pix[FG_X1] = p_x ;
  244.         pix[FG_Y1] = p_y ;
  245.     } else if ( pix[FG_X2] == -1 ) {
  246.         x1 = min( p_x, pix[FG_X1] ) ;
  247.         x2 = max( p_x, pix[FG_X1] ) ;
  248.         y1 = min( p_y, pix[FG_Y1] ) ;
  249.         y2 = max( p_y, pix[FG_Y1] ) ;
  250.         pix[FG_X2] = p_x ;
  251.         pix[FG_Y2] = p_y ;
  252.         pix[FG_X1] += dispbox[FG_X1] ;
  253.         pix[FG_X2] += dispbox[FG_X1] ;
  254.         pix[FG_Y1] += dispbox[FG_Y1] ;
  255.         pix[FG_Y2] += dispbox[FG_Y1] ;
  256.         msm_hidecursor() ;
  257.         fg_drawlineclip( get_color(), get_mode(), ~0, FG_LINE_SOLID,
  258.             pix, dispbox ) ;
  259.         msm_showcursor() ;
  260.         finish_func() ;
  261.         redraw( x1, y1, x2, y2 ) ;
  262.     }
  263. }
  264.  
  265. void editmap :: _set_draw_box () { set_funcname( draw_box, "BOX" ) ; }
  266.  
  267. void editmap :: draw_box () {
  268.  
  269.     fg_coord_t x1, y1, x2, y2 ;
  270.  
  271.     if ( pix[FG_X1] == -1 ) {
  272.         pix[FG_X1] = p_x ;
  273.         pix[FG_Y1] = p_y ;
  274.     } else if ( pix[FG_X2] == -1 ) {
  275.         x1 = min( p_x, pix[FG_X1] ) ;
  276.         x2 = max( p_x, pix[FG_X1] ) ;
  277.         y1 = min( p_y, pix[FG_Y1] ) ;
  278.         y2 = max( p_y, pix[FG_Y1] ) ;
  279.         pix[FG_X1] = dispbox[FG_X1] + x1 ;
  280.         pix[FG_X2] = dispbox[FG_X1] + x2 ;
  281.         pix[FG_Y1] = dispbox[FG_Y1] + y1 ;
  282.         pix[FG_Y2] = dispbox[FG_Y1] + y2 ;
  283.         msm_hidecursor() ;
  284.         fg_drawbox( get_color(), get_mode(), ~0, FG_LINE_SOLID,
  285.             pix, dispbox ) ;
  286.         msm_showcursor() ;
  287.         finish_func() ;
  288.         redraw( x1, y1, x2, y2 ) ;
  289.     }
  290. }
  291.  
  292. void editmap :: _set_invert_box () { set_funcname( invert_box, "INVERT" ) ; }
  293.  
  294. void editmap :: invert_box () {
  295.  
  296.     fg_coord_t x1, y1, x2, y2 ;
  297.  
  298.     if ( pix[FG_X1] == -1 ) {
  299.         pix[FG_X1] = p_x ;
  300.         pix[FG_Y1] = p_y ;
  301.     } else if ( pix[FG_X2] == -1 ) {
  302.         x1 = min( p_x, pix[FG_X1] ) ;
  303.         x2 = max( p_x, pix[FG_X1] ) ;
  304.         y1 = min( p_y, pix[FG_Y1] ) ;
  305.         y2 = max( p_y, pix[FG_Y1] ) ;
  306.         pix[FG_X1] = dispbox[FG_X1] + x1 ;
  307.         pix[FG_X2] = dispbox[FG_X1] + x2 ;
  308.         pix[FG_Y1] = dispbox[FG_Y1] + y1 ;
  309.         pix[FG_Y2] = dispbox[FG_Y1] + y2 ;
  310.         msm_hidecursor() ;
  311.         fg_fillbox( get_color(), FG_MODE_XOR, ~0, pix ) ;
  312.         msm_showcursor() ;
  313.         finish_func() ;
  314.         redraw( x1, y1, x2, y2 ) ;
  315.     }
  316. }
  317.  
  318. void editmap :: _set_flip_x () { set_funcname( flip_x, "FLIP X" ) ; }
  319.  
  320. void editmap :: flip_x () {
  321.  
  322.     fg_coord_t x1, y1, x2, y2, w, h, i, j ;
  323.     char **buf ;
  324.  
  325.     if ( pix[FG_X1] == -1 ) {
  326.         pix[FG_X1] = p_x ;
  327.         pix[FG_Y1] = p_y ;
  328.     } else if ( pix[FG_X2] == -1 ) {
  329.         x1 = min( p_x, pix[FG_X1] ) ;
  330.         x2 = max( p_x, pix[FG_X1] ) ;
  331.         y1 = min( p_y, pix[FG_Y1] ) ;
  332.         y2 = max( p_y, pix[FG_Y1] ) ;
  333.         w = x2 - x1 + 1 ;
  334.         h = y2 - y1 + 1 ;
  335.         buf = alloc_array( w, h ) ;
  336.         for ( i = 0 ; i < w ; i++ )
  337.             for ( j = 0 ; j < h ; j++ )
  338.                 buf[w - i - 1][j] = fg_readdot(
  339.                     x1 + dispbox[FG_X1] + i,
  340.                     y1 + dispbox[FG_Y1] + j ) == fgc ?
  341.                     1 : 0 ;
  342.         msm_hidecursor() ;
  343.         for ( i = 0 ; i < w ; i++ )
  344.             for ( j = 0 ; j < h ; j++ )
  345.                 fg_drawdot( buf[i][j] ? fgc : bgc,
  346.                     get_mode(), ~0,
  347.                     dispbox[FG_X1] + x1 + i,
  348.                     dispbox[FG_Y1] + y1 + j
  349.                 ) ;
  350.         msm_showcursor() ;
  351.         delete_array( buf, w ) ;
  352.         finish_func() ;
  353.         redraw( x1, y1, x2, y2 ) ;
  354.     }
  355. }
  356.  
  357. void editmap :: _set_flip_y () { set_funcname( flip_y, "FLIP Y" ) ; }
  358.  
  359. void editmap :: flip_y () {
  360.  
  361.     fg_coord_t x1, y1, x2, y2, w, h, i, j ;
  362.     char **buf ;
  363.  
  364.     if ( pix[FG_X1] == -1 ) {
  365.         pix[FG_X1] = p_x ;
  366.         pix[FG_Y1] = p_y ;
  367.     } else if ( pix[FG_X2] == -1 ) {
  368.         x1 = min( p_x, pix[FG_X1] ) ;
  369.         x2 = max( p_x, pix[FG_X1] ) ;
  370.         y1 = min( p_y, pix[FG_Y1] ) ;
  371.         y2 = max( p_y, pix[FG_Y1] ) ;
  372.         w = x2 - x1 + 1 ;
  373.         h = y2 - y1 + 1 ;
  374.         buf = alloc_array( w, h ) ;
  375.         for ( i = 0 ; i < w ; i++ )
  376.             for ( j = 0 ; j < h ; j++ )
  377.                 buf[i][h - j - 1] = fg_readdot(
  378.                     x1 + dispbox[FG_X1] + i,
  379.                     y1 + dispbox[FG_Y1] + j ) == fgc ?
  380.                     1 : 0 ;
  381.         msm_hidecursor() ;
  382.         for ( i = 0 ; i < w ; i++ )
  383.             for ( j = 0 ; j < h ; j++ )
  384.                 fg_drawdot( buf[i][j] ? fgc : bgc,
  385.                     get_mode(), ~0,
  386.                     dispbox[FG_X1] + x1 + i,
  387.                     dispbox[FG_Y1] + y1 + j
  388.                 ) ;
  389.         msm_showcursor() ;
  390.         delete_array( buf, w ) ;
  391.         finish_func() ;
  392.         redraw( x1, y1, x2, y2 ) ;
  393.     }
  394. }
  395.  
  396. void editmap :: _set_clear () { set_funcname( clear, "CLEAR" ) ; }
  397.  
  398. void editmap :: clear () {
  399.  
  400.     fg_coord_t x1, y1, x2, y2 ;
  401.  
  402.     if ( pix[FG_X1] == -1 ) {
  403.         pix[FG_X1] = p_x ;
  404.         pix[FG_Y1] = p_y ;
  405.     } else if ( pix[FG_X2] == -1 ) {
  406.         x1 = min( p_x, pix[FG_X1] ) ;
  407.         x2 = max( p_x, pix[FG_X1] ) ;
  408.         y1 = min( p_y, pix[FG_Y1] ) ;
  409.         y2 = max( p_y, pix[FG_Y1] ) ;
  410.         pix[FG_X1] = dispbox[FG_X1] + x1 ;
  411.         pix[FG_X2] = dispbox[FG_X1] + x2 ;
  412.         pix[FG_Y1] = dispbox[FG_Y1] + y1 ;
  413.         pix[FG_Y2] = dispbox[FG_Y1] + y2 ;
  414.         msm_hidecursor() ;
  415.         fg_fillbox( bgc, FG_MODE_SET, ~0, pix ) ;
  416.         msm_showcursor() ;
  417.         finish_func() ;
  418.         redraw( x1, y1, x2, y2 ) ;
  419.     }
  420. }
  421.  
  422. void editmap :: _set_copy () {
  423.  
  424.     set_funcname( copy, "COPY" ) ;
  425.     delete_array( clipb, clip_w ) ;
  426. }
  427.  
  428. void editmap :: copy () {
  429.  
  430.     fg_coord_t x1, y1, x2, y2, i, j ;
  431.  
  432.     if ( pix[FG_X1] == -1 ) {
  433.         pix[FG_X1] = p_x ;
  434.         pix[FG_Y1] = p_y ;
  435.     } else if ( pix[FG_X2] == -1 ) {
  436.         x1 = min( p_x, pix[FG_X1] ) ;
  437.         x2 = max( p_x, pix[FG_X1] ) ;
  438.         y1 = min( p_y, pix[FG_Y1] ) ;
  439.         y2 = max( p_y, pix[FG_Y1] ) ;
  440.         clip_w = x2 - x1 + 1 ;
  441.         clip_h = y2 - y1 + 1 ;
  442.         clipb = alloc_array( clip_w, clip_h ) ;
  443.         for ( i = x1 ; i <= x2 ; i++ )
  444.             for ( j = y1 ; j <= y2 ; j++ )
  445.                 clipb[i - x1][j - y1] =
  446.                     fg_readdot( dispbox[FG_X1] + i,
  447.                         dispbox[FG_Y1] + j ) == fgc ?
  448.                         1 : 0 ;
  449.         finish_func() ;
  450.     }
  451. }
  452.  
  453. void editmap :: _set_cut () {
  454.  
  455.     set_funcname( cut, "CUT" ) ;
  456.     delete_array( clipb, clip_w ) ;
  457. }
  458.  
  459. void editmap :: cut () {
  460.  
  461.     fg_coord_t x1, y1, x2, y2, i, j, k, m ;
  462.  
  463.     if ( pix[FG_X1] == -1 ) {
  464.         pix[FG_X1] = p_x ;
  465.         pix[FG_Y1] = p_y ;
  466.     } else if ( pix[FG_X2] == -1 ) {
  467.         x1 = min( p_x, pix[FG_X1] ) ;
  468.         x2 = max( p_x, pix[FG_X1] ) ;
  469.         y1 = min( p_y, pix[FG_Y1] ) ;
  470.         y2 = max( p_y, pix[FG_Y1] ) ;
  471.         clip_w = x2 - x1 + 1 ;
  472.         clip_h = y2 - y1 + 1 ;
  473.         clipb = alloc_array( clip_w, clip_h ) ;
  474.         for ( i = x1 ; i <= x2 ; i++ )
  475.             for ( j = y1 ; j <= y2 ; j++ ) {
  476.                 clipb[i - x1][j - y1] =
  477.                     fg_readdot( k = dispbox[FG_X1] + i,
  478.                         m = dispbox[FG_Y1] + j )
  479.                     == fgc ? 1 : 0 ;
  480.                 fg_drawdot( bgc, FG_MODE_SET, ~0, k, m ) ;
  481.             }
  482.         finish_func() ;
  483.         redraw( x1, y1, x2, y2 ) ;
  484.     }
  485. }
  486.  
  487. void editmap :: _set_paste () {
  488.  
  489.     set_funcname( paste, "PASTE" ) ;
  490. }
  491.  
  492. void editmap :: paste () {
  493.  
  494.     fg_coord_t i, j, k, m ;
  495.  
  496.     if ( pix[FG_X1] == -1 ) {
  497.         for ( i = 0 ; i < clip_w ; i++ )
  498.             for ( j = 0 ; j < clip_h ; j++ ) {
  499.                 k = dispbox[FG_X1] + p_x + i ;
  500.                 m = dispbox[FG_Y1] + p_y - j ;
  501.                 if ( fg_pt_inbox( dispbox, k, m ) )
  502.                     if ( clipb[i][clip_h - j - 1] )
  503.                         fg_drawdot( get_color(),
  504.                             get_mode(),~0, k, m ) ;
  505.             }
  506.         finish_func() ;
  507.         redraw( p_x, p_y - clip_h + 1, p_x + clip_w - 1, p_y ) ;
  508.     }
  509. }
  510.  
  511. void editmap :: _set_draw_circle () { set_funcname( draw_circle, "CIRCLE" ) ;}
  512.  
  513. void editmap :: draw_circle () {
  514.  
  515.     double radiu ;
  516.     int x, y, r ;
  517.     fg_coord_t x1, y1, x2, y2 ;
  518.  
  519.     if ( pix[FG_X1] == -1 ) {
  520.         pix[FG_X1] = p_x ;
  521.         pix[FG_Y1] = p_y ;
  522.     } else if ( pix[FG_X2] == -1 ) {
  523.         x = p_x - pix[FG_X1] ;
  524.         y = p_y - pix[FG_Y1] ;
  525.         radiu = sqrt( x * x + y * y ) ;
  526.         r = int( radiu ) ;
  527.         x1 = pix[FG_X1] - r ; x2 = pix[FG_X1] + r ;
  528.         y1 = pix[FG_Y1] - r ; y2 = pix[FG_Y1] + r ;
  529.         pix[FG_X1] += dispbox[FG_X1] ;
  530.         pix[FG_Y1] += dispbox[FG_Y1] ;
  531.         msm_hidecursor() ;
  532.         fg_drawarc( get_color(), get_mode(), ~0,
  533.             pix[FG_X1], pix[FG_Y1], r, 0, 3600, dispbox ) ;
  534.         msm_showcursor() ;
  535.         finish_func() ;
  536.         redraw( x1, y1, x2, y2 ) ;
  537.     }
  538. }
  539.  
  540. void editmap :: _set_draw_ellipse () {
  541.  
  542.     set_funcname( draw_ellipse, "ELLIPSE" ) ;
  543. }
  544.  
  545. void editmap :: draw_ellipse () {
  546.  
  547.     int x, y, r, s ;
  548.     fg_coord_t x1, y1, x2, y2 ;
  549.  
  550.     if ( pix[FG_X1] == -1 ) {
  551.         pix[FG_X1] = p_x ;
  552.         pix[FG_Y1] = p_y ;
  553.     } else if ( pix[FG_X2] == -1 ) {
  554.         x = min( p_x, pix[FG_X1] ) ;
  555.         y = min( p_y, pix[FG_Y1] ) ;
  556.         r = x == p_x ? pix[FG_X1] - x : p_x - x ;
  557.         s = y == p_y ? pix[FG_Y1] - y : p_y - y ;
  558.         x1 = x - r ; x2 = x + r ; y1 = y - s ; y2 = y + s ;
  559.         x += dispbox[FG_X1] ;
  560.         y += dispbox[FG_Y1] ;
  561.         msm_hidecursor() ;
  562.         fg_drawellipse( get_color(), get_mode(), ~0, x, y, r, s,
  563.             0, 3600, dispbox ) ;
  564.         msm_showcursor() ;
  565.         finish_func() ;
  566.         redraw( x1, y1, x2, y2 ) ;
  567.     }
  568. }
  569.  
  570. void editmap :: _set_draw_pixel () { set_funcname( draw_pixel, "PIXEL" ) ; }
  571.  
  572. void editmap :: draw_pixel () {
  573.  
  574.     if ( pix[FG_X1] == -1 ) {
  575.         bits[p_x][p_y] = p_status == MSM_BUTTONL ? 1 : 0 ;
  576.         msm_hidecursor() ;
  577.         drawcell( p_x, p_y, 1 ) ;
  578.         msm_showcursor() ;
  579.         finish_func() ;
  580.     }
  581. }
  582.  
  583. void editmap :: edit_map () {
  584.  
  585.     getmspos() ;
  586.     translate() ;
  587.     msm_hidecursor() ;
  588.     drawcell( p_x, p_y, 0 ) ;
  589.     msm_showcursor() ;
  590.     ( this->*draw_func )() ;
  591. }
  592. void editmap :: total_map () {
  593.  
  594.     getmspos() ;
  595.     mu->box->translate_script( this, p_x, p_y ) ;
  596. }
  597.  
  598. void editmap :: drawcell ( int i, int j, int f ) {
  599.  
  600.     fg_box_t t ;
  601.     fg_coord_t g, k ;
  602.  
  603.     if ( i < 0 || i >= w || j < 0 || j >= h )
  604.         return ;
  605.     g = editbox[FG_X1] + i * cellbox[FG_X2] ;
  606.     k = editbox[FG_Y1] + j * cellbox[FG_Y2] ;
  607.     fg_make_box( t, g, k, g + cellbox[FG_X2] - 1, k + cellbox[FG_Y2] - 1 ) ;
  608.     if ( f ) {
  609.         fg_fillbox( bits[i][j] ? fgc : bgc, FG_MODE_SET, ~0, t ) ;
  610.         fg_drawdot( bits[i][j] ? fgc : bgc, FG_MODE_SET, ~0,
  611.             dispbox[FG_X1] + i, dispbox[FG_Y1] + j ) ;
  612.         t[FG_X2]++ ; t[FG_Y2]++ ;
  613.         fg_drawbox( fgc, FG_MODE_SET, ~0, FG_LINE_SOLID, t, winbox ) ;
  614.     } else {
  615.         fg_drawline( fgc, FG_MODE_XOR, ~0, FG_LINE_SOLID, t ) ;
  616.         g = t[FG_X1] ; t[FG_X1] = t[FG_X2] ; t[FG_X2] = g ;
  617.         fg_drawline( fgc, FG_MODE_XOR, ~0, FG_LINE_SOLID, t ) ;
  618.     }        
  619. }
  620.  
  621. void editmap :: expose () {
  622.  
  623.     int i, j, k ;
  624.     fg_coord_t m, n ;
  625.     fg_box_t t ;
  626.  
  627.     msm_hidecursor() ;
  628.     cls() ;
  629.     for ( i = 0 ; i < w ; i++ )
  630.         for ( j = 0 ; j < h ; j++ )
  631.             drawcell( i, j, 1 ) ;
  632.  
  633.     for ( i = 0 ; i < w ; i += 10 )
  634.         for ( k = 1, j = i ; j < i + 10 && j < w ; k--, j += 5 ) {
  635.             m = editbox[FG_X1] + j * cellbox[FG_X2] ;
  636.             n = editbox[FG_Y1] - 2 ;
  637.             fg_make_box( t, m,
  638.                 editbox[FG_Y1] - fg.charbox[FG_Y2] / 2,
  639.                 m, n ) ;
  640.             if ( !j )
  641.                 continue ;
  642.             if ( k )
  643.                 t[FG_Y1] -= fg.charbox[FG_Y2] / 2 ;
  644.             fg_drawlineclip( fgc, FG_MODE_SET, ~0,
  645.                 FG_LINE_SOLID, t, winbox );
  646.         }
  647.  
  648.     for ( i = 0 ; i < h ; i += 10 )
  649.         for ( k = 1, j = i ; j < i + 10 && j < h ; k--, j += 5 ) {
  650.             m = editbox[FG_Y1] + j * cellbox[FG_Y2] ;
  651.             n = editbox[FG_X1] - 2 ;
  652.             fg_make_box( t, editbox[FG_X1] - fg.charbox[FG_X2] / 2,
  653.                 m, n, m ) ;
  654.             if ( !j )
  655.                 continue ;
  656.             if ( k )
  657.                 t[FG_X1] -= fg.charbox[FG_X2] / 2 ;
  658.             fg_drawlineclip( fgc, FG_MODE_SET, ~0,
  659.                 FG_LINE_SOLID, t, winbox ) ;
  660.         }
  661.  
  662.     fg_box_cpy( t, dispbox ) ;
  663.     t[FG_X1]-- ; t[FG_Y1]-- ; t[FG_X2]++ ; t[FG_Y2]++ ;
  664.     fg_drawbox( fgc, FG_MODE_SET, ~0, FG_LINE_SOLID, t, winbox);
  665.     msm_showcursor() ;
  666.     mu->expose() ;
  667. }
  668.  
  669. void editmap :: redraw ( int _x1, int _y1, int _x2, int _y2 ) {
  670.  
  671.     int i, j ;
  672.     fg_box_t t ;
  673.     fg_coord_t p, q, x1, y1, x2, y2 ;
  674.  
  675.     msm_hidecursor() ;
  676.     p = dispbox[FG_X1] ;
  677.     q = dispbox[FG_Y1] ;
  678.     x1 = max( _x1, 0 ) ;
  679.     y1 = max( _y1, 0 ) ;
  680.     x2 = min( _x2, w - 1 ) ;
  681.     y2 = min( _y2, h - 1 ) ;
  682.     for ( i = x1 ; i <= x2 ; i++ )
  683.         for ( j = y1 ; j <= y2 ; j++ ) {
  684.             bits[i][j] = fg_readdot( p + i, q + j )
  685.                 == bgc ? 0 : 1 ;
  686.             drawcell( i, j, 1 ) ;
  687.         }
  688.     fg_box_cpy( t, dispbox ) ;
  689.     t[FG_X1]-- ; t[FG_Y1]-- ; t[FG_X2]++ ; t[FG_Y2]++ ;
  690.     fg_drawbox( fgc, FG_MODE_SET, ~0, FG_LINE_SOLID, t, winbox);
  691.     msm_showcursor() ;
  692. }
  693.  
  694. void editmap :: _redraw () { redraw( 0, 0, w - 1, h - 1 ) ; }
  695.  
  696. void editmap :: focus () { focus_loop( this ) ; }
  697.  
  698. void editmap :: destroy () { quit = 1 ; }
  699.  
  700.